using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using CHEnhanceEfCore.Annotation.auth;
using CHEnhanceEfCore.Common;
using CHEnhanceEfCore.Config.Cache;
using CHEnhanceEfCore.Constant;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;

namespace CHEnhanceEfCore.Filter
{
    /// <summary>
    /// author: chenhao
    /// </summary>                                                   
    public class PermissionAuthorizationFilter : IAuthorizationFilter
    {
        private readonly ICacheContext _cacheContext;

        public PermissionAuthorizationFilter(ICacheContext cacheContext)
        {
            _cacheContext = cacheContext;
        }

        /**
          * 若需要进行测试 注释该方法
          */
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            try
            {
                PathString path = context.HttpContext.Request.Path;
                //可以封装到一个map中
                if (path.Value!.Contains("/login") || path.Value!.Contains("/health"))
                {
                    return;
                }

                IHeaderDictionary headers = context.HttpContext.Request.Headers;
                string tokenStr = headers["Authorization"];
                string token = tokenStr.Replace("Bearer ", "").Trim();
                //反解析token
                JwtSecurityToken jwtSecurityToken = JwtHelper.reverseParseToken(token);
                string userId = jwtSecurityToken.Claims.Where(c => c.Type.Equals("userId")).Select(claim => claim.Value).FirstOrDefault();
                List<string> permissionList = _cacheContext.Get<List<string>>($"{UserCacheConstant.USER_PERMISSIONS_CACHE}{userId}");
                if (null == permissionList)
                {
                    //获取permission的字符串
                    string permissionStr = jwtSecurityToken.Claims.Where(claim => claim.Type.Equals("permission")).Select(claim => claim.Value)
                        .FirstOrDefault();

                    //逗号分割
                    permissionList = permissionStr!.Split(",").ToList();
                    //将permissionList存入cache
                    _cacheContext.Set($"{UserCacheConstant.USER_PERMISSIONS_CACHE}{userId}", permissionList, DateTime.Now.AddHours(24));
                    context.HttpContext.Request.Headers.TryAdd(UserTaskConstant.USER_ID_HEADER,  jwtSecurityToken.Claims.Where(claim => claim.Type.Equals("userId")).Select(claim => claim.Value).FirstOrDefault());
                }

                //获取action的方法属性
                var methodInfo = (context.ActionDescriptor as ControllerActionDescriptor)?.MethodInfo;
                if (methodInfo == null)
                {
                    return;
                }

                if (methodInfo.GetCustomAttributes(typeof(PermissionAttribute), true).FirstOrDefault() is not PermissionAttribute attribute)
                {
                    return;
                }

                // 获取注解中的属性值
                string annotationValue = attribute.value;
                //校验是否有该接口权限
                if (!permissionList.Contains(annotationValue))
                {
                    // 如果权限验证失败，返回未授权结果
                    context.Result = new UnauthorizedResult();
                }
            }
            catch (Exception)
            {
                context.Result = new UnauthorizedResult();
            }
        }
    }
}